package mailclient;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMultipart;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Vipar
 */
public class MailPanel extends javax.swing.JPanel {
    private DefaultTableModel model;
    private Message[] message;
    /**
     * Creates new form MailPanel
     */
    public MailPanel() {
        initComponents();
        model = new DefaultTableModel();
        model.addColumn("From");
        model.addColumn("Subject");
        model.addColumn("Is Read");
        model.addColumn("Date Received");
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        paneParent = new javax.swing.JPanel();
        mailUserNameLabel = new javax.swing.JLabel();
        mailUserNameField = new javax.swing.JTextField();
        mailExtensionBox = new javax.swing.JComboBox();
        mailPasswordLabel = new javax.swing.JLabel();
        mailPasswordField = new javax.swing.JPasswordField();
        fillerPane = new javax.swing.JPanel();
        mailFetchBtn = new javax.swing.JButton();
        mailClearBtn = new javax.swing.JButton();
        tableScroll = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        mailStatusLabel = new javax.swing.JLabel();

        setMaximumSize(new java.awt.Dimension(2147483647, 2147483647));
        setPreferredSize(new java.awt.Dimension(0, 0));

        paneParent.setLayout(new java.awt.GridLayout(0, 3));

        mailUserNameLabel.setText("Username");
        paneParent.add(mailUserNameLabel);
        paneParent.add(mailUserNameField);

        mailExtensionBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "GMail", "Hotmail", "Yahoo! Mail" }));
        paneParent.add(mailExtensionBox);

        mailPasswordLabel.setText("Password");
        paneParent.add(mailPasswordLabel);
        paneParent.add(mailPasswordField);

        javax.swing.GroupLayout fillerPaneLayout = new javax.swing.GroupLayout(fillerPane);
        fillerPane.setLayout(fillerPaneLayout);
        fillerPaneLayout.setHorizontalGroup(
            fillerPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 139, Short.MAX_VALUE)
        );
        fillerPaneLayout.setVerticalGroup(
            fillerPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 26, Short.MAX_VALUE)
        );

        paneParent.add(fillerPane);

        mailFetchBtn.setText("Fetch Emails");
        mailFetchBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mailFetchBtnActionPerformed(evt);
            }
        });
        paneParent.add(mailFetchBtn);

        mailClearBtn.setText("Clear Table");
        mailClearBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mailClearBtnActionPerformed(evt);
            }
        });
        paneParent.add(mailClearBtn);

        tableScroll.setMaximumSize(new java.awt.Dimension(2147483647, 2147483647));
        tableScroll.setMinimumSize(new java.awt.Dimension(500, 500));
        tableScroll.setPreferredSize(new java.awt.Dimension(500, 500));

        table.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "From", "Subject", "Is Read"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        table.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        table.setMaximumSize(new java.awt.Dimension(2147483647, 2147483647));
        table.setMinimumSize(new java.awt.Dimension(500, 500));
        table.getTableHeader().setReorderingAllowed(false);
        table.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                tableMouseReleased(evt);
            }
        });
        tableScroll.setViewportView(table);

        mailStatusLabel.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
        mailStatusLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(paneParent, javax.swing.GroupLayout.PREFERRED_SIZE, 417, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(mailStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addComponent(tableScroll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(paneParent, javax.swing.GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)
                    .addComponent(mailStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tableScroll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void clear() {
        while(model.getRowCount() > 0) {
            model.removeRow(0);
        }
    }
    
    @SuppressWarnings("unchecked")
    private void mailFetchBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mailFetchBtnActionPerformed
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                if(mailUserNameField.getText().isEmpty()) {
                    JOptionPane.showMessageDialog(paneParent, "Please fill in a valid mail",
                            "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                String username = mailUserNameField.getText();
                if(mailPasswordField.getPassword().length == 0) {
                    JOptionPane.showMessageDialog(paneParent, "Password field cannot be empty",
                            "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                StringBuilder sb = new StringBuilder();
                for(char c : mailPasswordField.getPassword()) {
                    sb.append(c);
                }
                message = null;
                mailStatusLabel.setText("Fetching...");
                mailClearBtn.setEnabled(false);
                mailFetchBtn.setEnabled(false);
                clear();
                try {
                    switch(mailExtensionBox.getSelectedIndex()) {
                        /**
                         * 0: Gmail
                         * 1: Hotmail
                         * 2: Yahoo
                         */
                        case 0:
                            GMailFetcher gmf = new GMailFetcher();
                            gmf.setAccountDetails(username, sb.toString());
                            message = gmf.readGmail();
                            break;
                        case 1:
                            HotmailFetcher hmf = new HotmailFetcher();
                            hmf.setAccountDetails(username, sb.toString());
                            message = hmf.readHotmail();
                            break;
                        case 2:
                            YahooFetcher ymf = new YahooFetcher();
                            ymf.setAccountDetails(username, sb.toString());
                            message = ymf.readYahooMail();
                            break;
                    }
                } catch (Exception e) {
                            JOptionPane.showMessageDialog(paneParent, "An Error Occured:\n" + e.getMessage(),
                                    "Error", JOptionPane.ERROR_MESSAGE);
                            mailStatusLabel.setText("Error");
                            mailClearBtn.setEnabled(true);
                            mailFetchBtn.setEnabled(true);
                        }
                try {
                    if(message.length == 0 || message == null) {
                        JOptionPane.showMessageDialog(paneParent, "You don't have any emails in your Inbox",
                            "Information", JOptionPane.INFORMATION_MESSAGE);
                        mailStatusLabel.setText("Error");
                        mailClearBtn.setEnabled(true);
                        mailFetchBtn.setEnabled(true);
                    }
                    for(int i = 0; i < message.length; i++) {
                        String from = InternetAddress.toString(message[i].getFrom());
                        String subject = message[i].getSubject();
                        String isRead = (message[i].getFlags().contains(Flags.Flag.SEEN) ? "Yes" : "No");
                        String dateReceived = message[i].getSentDate().toString();
                        model.addRow(new Object[]{from,subject,isRead,dateReceived});
                    }
                    mailStatusLabel.setText("Done");
                    mailClearBtn.setEnabled(true);
                    mailFetchBtn.setEnabled(true);
                } catch (MessagingException ex) {
                    JOptionPane.showMessageDialog(paneParent, "An Error Occured:\n" + ex.getMessage(),
                            "Error", JOptionPane.ERROR_MESSAGE);
                    mailStatusLabel.setText("Error");
                    mailClearBtn.setEnabled(true);
                    mailFetchBtn.setEnabled(true);
                }
            }
        });
        t2.start();
        table.setModel(model);
    }//GEN-LAST:event_mailFetchBtnActionPerformed

    private void mailClearBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mailClearBtnActionPerformed
        clear();
        table.setModel(model);
    }//GEN-LAST:event_mailClearBtnActionPerformed

    private void tableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseReleased
        final java.awt.event.MouseEvent e = evt;
        Thread t = new Thread(new Runnable() {
            @Override
           public void run() {
               if(table.getRowCount() == 0 || message == null || message.length == 0) {
            // Do nothing
        } else {
            try {
                int row = table.rowAtPoint(e.getPoint());                
                String subject = message[row].getSubject();
                String from = InternetAddress.toString(message[row].getFrom());
                StringBuilder body = new StringBuilder();
                Multipart mp = (Multipart) message[row].getContent();
                for(int i = 0; i < mp.getCount(); i++) {
                    BodyPart bp = mp.getBodyPart(i);
                    String disp = bp.getDisposition();
                    if(disp != null && (disp.equals(BodyPart.ATTACHMENT))) {
                        // Do something
                    } else {
                        body.append(bp.getContent());
                    }
                }
                EmailContent ec = new EmailContent(new JFrame(),true,from,subject,"<html>" + body.toString());
            } catch (IOException ex) {
                Logger.getLogger(MailPanel.class.getName()).log(Level.SEVERE, null, ex);
            } catch (MessagingException ex) {
                Logger.getLogger(MailPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
           } 
        });
        t.start();
    }//GEN-LAST:event_tableMouseReleased

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel fillerPane;
    private javax.swing.JButton mailClearBtn;
    private javax.swing.JComboBox mailExtensionBox;
    private javax.swing.JButton mailFetchBtn;
    private javax.swing.JPasswordField mailPasswordField;
    private javax.swing.JLabel mailPasswordLabel;
    private javax.swing.JLabel mailStatusLabel;
    private javax.swing.JTextField mailUserNameField;
    private javax.swing.JLabel mailUserNameLabel;
    private javax.swing.JPanel paneParent;
    private javax.swing.JTable table;
    private javax.swing.JScrollPane tableScroll;
    // End of variables declaration//GEN-END:variables
}
